﻿namespace BM.Tools.WebControls.MForm.Controls.Modifiers
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    using BM.Tools.WebControls.MForm.Controls.Helper;
    using BM.Tools.WebControls.MForm.Controls.Items;
    using BM.Tools.WebControls.MForm.Controls.Modifiers.Additions;
    using BM.Tools.WebControls.MForm.Navigation;
    using BM.Tools.WebControls.MForm.ScriptReferences;

    /// <summary>
    /// A modifier that changes the display of the control, to look like a table.
    /// the children are laid out horizontally, and the siblings are laid out vertically.
    /// </summary>
    public class HorizontalTableDisplayModifier : TableDisplayModifier, IDisposable
    {
        private const string HorizontalHeaderCssClass = "HH";

        private const string HorizontalRecordCssClass = "HR";

        private FormStyle cellStyle;

        private FormStyle rowStyle;

        /// <summary>
        /// Gets CellStyle.
        /// </summary>
        /// <value>
        /// The cell style.
        /// </value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [NotifyParentProperty(true)]
        [Category("Styles")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public FormStyle CellStyle
        {
            get
            {
                if (cellStyle == null)
                {
                    cellStyle = new FormStyle
                                {
                                        Width = new Unit(180)
                                };
                }

                return cellStyle;
            }
        }

        /// <summary>
        /// Gets RowStyle.
        /// </summary>
        /// <value>
        /// The row style.
        /// </value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [NotifyParentProperty(true)]
        [Category("Styles")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public FormStyle RowStyle
        {
            get
            {
                if (rowStyle == null)
                {
                    rowStyle = new FormStyle();
                }

                return rowStyle;
            }
        }

        /// <summary>
        /// Gets TitleCssClass.
        /// </summary>
        protected override string TitleCssClass
        {
            get
            {
                return HorizontalHeaderCssClass;
            }
        }

        /// <summary>
        /// Disposes the control
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Registers styles on the page so that items look like a table.
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        protected override void AddStyles(OffspringsOwner offspring)
        {
            string siblingsCss = GetCommonSiblingsHash(offspring);
            string cellWidth = Convert.ToString(90 / GetCellCount(offspring), CultureInfo.InvariantCulture) + "%";
            CellStyle.Width = new Unit(cellWidth, CultureInfo.InvariantCulture);

            ScriptIncluder.CreateOrGetHeader(offspring.Page).StyleSheet.CreateStyleRule(
                    RowStyle, null, String.Concat(".", siblingsCss));
            ScriptIncluder.CreateOrGetHeader(offspring.Page).StyleSheet.CreateStyleRule(
                    CellStyle, null, String.Concat(".", siblingsCss, " .Lf"));
        }

        /// <summary>
        /// Disposes the control
        /// </summary>
        /// <param name="disposing">
        /// The disposing.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (rowStyle != null)
                {
                    rowStyle.Dispose();
                }

                if (cellStyle != null)
                {
                    cellStyle.Dispose();
                }
            }
        }

        /// <summary>
        /// Creates css styles for children, adds css classes to children, defines additions for children
        /// </summary>
        /// <param name="offspringItem">
        /// The offspring item.
        /// </param>
        /// <param name="args">
        /// The event args.
        /// </param>
        protected override void OnItemPreRender(OffspringsOwnerItem offspringItem, EventArgs args)
        {
            offspringItem.Title.Text = string.Empty;
            string siblingsCss = GetCommonSiblingsHash(offspringItem.Basis);
            offspringItem.CssClasses.Add(HorizontalRecordCssClass, siblingsCss);
            offspringItem.Additions.Add(new HorizontalTableDisplayAddition());
        }

        private static int GetCellCount(Offspring offspring)
        {
            return offspring.Items[0].Select("*").Leafs().Where(leafItem => leafItem.Visible).Count();
        }
    }
}